home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / swags-z / sorting.swg / 0052_Very FAST Shell Sort.pas < prev    next >
Pascal/Delphi Source File  |  1995-03-03  |  5KB  |  202 lines

  1. {$A+,B-,D+,E-,F-,G+,I-,L+,N-,O-,R+,S+,V-,X+,M 4096,0,655360
  2. NSORT version 3. Uses Shell sort instead of Insertion sort. Damn fast, still
  3. handles all that can fit into conventional memory.
  4. }
  5.  
  6. uses dos;
  7.  
  8. type
  9.  pstring=^string;
  10.  prec=^rec;
  11.  rec=record
  12.   s:pstring;
  13.   n:prec;
  14.  end;
  15.  
  16. const
  17.  rsize=sizeof(rec);
  18.  
  19. var
  20.  linet,linec:longint; {line total, current}
  21.  list,start,lstptr,next:prec;
  22.  {list,
  23.   start of sorting zone,
  24.   list stroller,
  25.   next item to be swapped}
  26.  infile,outfile,tmpline:string; {file names, input line}
  27.  textf:text; {input/output file variable}
  28.  tbuf:array [1..8192] of char; {text file buffer}
  29.  
  30. procedure progress;
  31. var
  32.  ctr,indicator:byte; {show graphically, how many blocks}
  33. begin
  34.  inc(linec); {increase current line}
  35.  indicator:=100*linec div linet; {get %}
  36.  write(indicator:5,'%  ');
  37.  indicator:=indicator div 5; {get 1/20th portion}
  38.  for ctr:=1 to 20 do
  39.   if ctr<=indicator then write('o') {o=5% done, .=5% remaining}
  40.   else write('.');
  41.  write(^m); {only carriage return: not new line too}
  42. end;
  43.  
  44. procedure TheEnd; far;
  45. begin
  46.  exitproc:=nil;
  47.  case exitcode of
  48.   1:writeln('Input file not found');
  49.   2:writeln('Can''t open input file');
  50.   3:writeln('Out of memory');
  51.   4:writeln('Can''t create output file');
  52.   5:writeln('Can''t finish output file');
  53.   6:writeln('Insufficient disk space');
  54.  end;
  55.  writeln('NSort version 3.');
  56.  writeln('NetRunner of Assassin Technologies. Lum''s Place 613 531 1911');
  57. end;
  58.  
  59. procedure checkfit;
  60. var
  61.  f:file;
  62.  size:longint;
  63.  drive:string[1];
  64. begin
  65.  if infile<>outfile then begin
  66.   assign(f,infile);
  67.   reset(f,1);
  68.   size:=filesize(f);
  69.   drive:=fexpand(outfile);
  70.   dec(drive[1],byte('A')-1);
  71.   if size>diskfree(byte(drive[1])) then halt(6);
  72.  end;
  73. end;
  74.  
  75. procedure showhelp;
  76. begin
  77.  writeln('Heavy duty sorter. Syntax: NSORT infile outfile | /s');
  78.  writeln('/s= use input name as output.');
  79.  writeln('Batch file exit codes:');
  80.  writeln('1 Input file not found');
  81.  writeln('2 Can''t open input file');
  82.  writeln('3 Out of memory');
  83.  writeln('4 Can''t create output file');
  84.  writeln('5 Can''t finish output file');
  85.  writeln('6 Insufficient disk space');
  86.  halt;
  87. end;
  88.  
  89. procedure swap(var p1,p2:pstring);
  90. var tmpptr:pstring;
  91. begin
  92.  tmpptr:=p1;
  93.  p1:=p2;
  94.  p2:=tmpptr;
  95. end;
  96.  
  97. Function upstr(s:string):string;
  98. var c:byte;
  99. begin
  100.  if length(s)>0 then for c:=1 to length(s) do s[c]:=upcase(s[c]);
  101.  upstr:=s;
  102. end;
  103.  
  104. Function fexist(fn:pathstr):boolean;
  105. var f:file; it:word;
  106. begin
  107.  assign(f,fn);
  108.  getfattr(f,it);
  109.  fexist:=doserror=0;
  110.  doserror:=0;
  111. end;
  112.  
  113. function malloc(var p; ram:word):boolean;
  114. begin
  115.  if (maxavail>=ram) then begin
  116.   if ram=0 then pointer(p):=nil {0 is OK but not an allocation}
  117.   else getmem(pointer(p),ram); {allocate if RAM > 0}
  118.   malloc:=true
  119.  end
  120.  else begin {not enough RAM}
  121.   malloc:=false;
  122.   pointer(p):=nil
  123.  end
  124. end;
  125.  
  126. begin
  127.  exitproc:=@TheEnd; {set exit procedure}
  128.  linec:=0; {init}
  129.  linet:=0;
  130.  
  131.  if paramcount=0 then showhelp; {show online help, no cmd line}
  132.  
  133.  {set input/output files}
  134.  
  135.  infile:=upstr(paramstr(1));
  136.  outfile:=upstr(paramstr(2));
  137.  if outfile='/S' then outfile:=infile; {/s as output file = same name}
  138.  
  139.  if not fexist(infile) then halt(1); {stop if input doesn't exist}
  140.  
  141.  checkfit; {if output file too large/not enough space, this finds it}
  142.  
  143.  assign(textf,infile); {set input file}
  144.  settextbuf(textf,tbuf); {set text buffer for speed}
  145.  
  146.  reset(textf);
  147.  if ioresult<>0 then halt(2); {stop if error opening file}
  148.  
  149.  list:=nil;
  150.  
  151.  {input file processing}
  152.  
  153.  while not eof(textf) do begin
  154.   readln(textf,tmpline); {get input}
  155.   inc(linet); {total line count, setup in loop}
  156.   if list=nil then begin {if list doesn't exist yet}
  157.    if not malloc(pointer(list),rsize) then halt(3); {allocate linked list rec}
  158.    next:=list; {next used to advance linked list}
  159.   end
  160.   else begin {current piece of list is not 1st}
  161.    if not malloc(pointer(next^.n),rsize) then halt(3); {alloc linked list node}
  162.    next:=next^.n; {advance placeholder}
  163.   end;
  164.   if not malloc(pointer(next^.s),length(tmpline)+1) then halt(3); {allocate
  165. line}  move(tmpline,next^.s^,length(tmpline)+1);
  166.   next^.n:=nil; {set list end = nil}
  167.  end;
  168.  close(textf); {close input file}
  169.  
  170.  {sorting begins here}
  171.  
  172.  start:=list;
  173.  while start<>nil do begin
  174.   next:=start;
  175.   lstptr:=start;
  176.   while lstptr<>nil do begin
  177.    if lstptr^.s^ < next^.s^ then next:=lstptr;
  178.    lstptr:=lstptr^.n; {advance list pointer}
  179.   end;
  180.   swap(start^.s,next^.s);
  181.   progress;
  182.   start:=start^.n; {advance start zone boundary, gradual reduction}
  183.  end;
  184.  writeln;
  185.  
  186.  {file output after complete sorting}
  187.  
  188.  lstptr:=list;
  189.  assign(textf,outfile);
  190.  rewrite(textf);
  191.  if ioresult<>0 then halt(4);
  192.  while lstptr<>nil do begin
  193.   writeln(textf,lstptr^.s^);
  194.   if ioresult<>0 then begin
  195.    close(textf);
  196.    halt(5);
  197.   end;
  198.   lstptr:=lstptr^.n;
  199.  end;
  200.  close(textf);
  201. end.
  202.